const { lockKey } = require('./redisConstant');
const BaseResult = require('./baseResp');
const ErrorCode = require('./errorCode');
const CacheFactory = require('./cacheFactory');

class LockUtil {
  /**
   * 构造函数
   * @param type  锁类型
   * @param id 关键字，一般为用户ID
   * @param expire 锁超时时间
   */
  constructor(type, id, expire = 120) {
    if (!type) throw new Error('锁类型不能为空');
    if (!id) throw new Error('锁编号不能为空');
    if (typeof expire !== 'number' || expire <= 0) throw new Error('锁超时时间不正确');
    this.expire = expire;
    this.lockKey = LockUtil.getLockKey(type, id);
  }

  /**
   * 获取请求队列lockKey
   * @param type 锁类型
   * @param id  锁编号
   * @returns {*|string|void}
   * @private
   */
  static getLockKey(type, id) {
    return lockKey.replace('$type', type).replace('$id', id);
  }

  /**
   * 尝试获取锁
   * @returns {Promise}
   */
  async tryLock() {
    this.lockTime = Date.now();
    const lock = await CacheFactory.getInstance().setNx(this.lockKey, 1, this.expire);
    console.log('.....',lock);
    if (!lock) throw BaseResult.error(ErrorCode.FREQUENT_REQUEST);
    console.log('获取请求锁：', this.lockKey);
  }

  /**
   * 释放锁
   * @returns {*|string|void}
   */
  async unlock() {
    if (this.isExpired()) {
      console.log(`请求锁(${this.lockKey})已超时自动释放`);
      return;
    }
    console.log('释放请求锁：', this.lockKey);
    await CacheFactory.getInstance().del(this.lockKey);
  }

  /**
   * 检查锁是否超时
   * @returns {*|string|void}
   */
  isExpired() {
    return Date.now() - this.lockTime >= this.expire * 1000;
  }
}

module.exports = LockUtil;
